package com.spgf.model.rn;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import android.annotation.SuppressLint;
import android.content.Context;

import com.archtecture.model.enuns.Mensagem;
import com.archtecture.model.exceptions.NegocioException;
import com.archtecture.model.patterns.PadraoRNAb;
import com.spgf.model.dao.LancamentoDAO;
import com.spgf.model.dao.util.CustomSQLiteOpenHelper;
import com.spgf.model.dao.util.PadraoDAOAb;
import com.spgf.model.entities.CategoriaModel;
import com.spgf.model.entities.LancamentoModel;
import com.spgf.model.enums.FormaPagamento;
import com.spgf.model.enums.Mes;
import com.spgf.model.utils.AndroidUtil;
import com.spgf.model.utils.ConstantesSPGF;

public class LancamentoRN extends PadraoRNAb<LancamentoModel> {

	public LancamentoRN(final Context context) {
		super(context);
	}

	@Override
	public LancamentoModel inserir(LancamentoModel pModel) throws NegocioException {

		verificarDespesasCartaoCredito(pModel);

		return pModel;
	}

	private void verificarDespesasCartaoCredito(LancamentoModel pModel) throws NegocioException {

		int lIterParcela = 1;

		do {

			LancamentoModel lLancamento = (LancamentoModel) pModel.getClone();

			if (pModel.getNumeroParcelas() > 1) {

				lLancamento.setObservacao(lLancamento.getObservacao() + " (" + lIterParcela + "/" + lLancamento.getNumeroParcelas() + ")");

				Calendar lCal = Calendar.getInstance();
				lCal.setTime(lLancamento.getData());

				if (lCal.get(Calendar.DAY_OF_MONTH) >= ConstantesSPGF.DIA_FECHAMENTO_FATURA) {
					lCal.add(Calendar.MONTH, lIterParcela);
				}

				lCal.set(Calendar.DAY_OF_MONTH, ConstantesSPGF.DIA_VENCIMENTO_FATURA_CARTAO);

				lLancamento.setData(lCal.getTime());

				lLancamento.setValor(lLancamento.getValor() / lLancamento.getNumeroParcelas());
			}

			super.inserir(lLancamento);

			lIterParcela++;

		}

		while (lIterParcela <= pModel.getNumeroParcelas());

	}

	public Double calcularValorTotal() throws NegocioException {

		LancamentoModel lModel = new LancamentoModel();

		List<LancamentoModel> lLancamentos = obterPorFiltro(lModel);

		Double lValorTotal = 0D;
		for (LancamentoModel lancamentoModel : lLancamentos) {
			lValorTotal += lancamentoModel.getValor();
		}

		return lValorTotal;
	}

	// @SuppressLint("SimpleDateFormat")
	// public List<LancamentoModel> obterLancamentosPorMes(LancamentoModel model) throws NegocioException {
	//
	// final Calendar calAtual = Calendar.getInstance();
	//
	// if (model.getData() != null) {
	// calAtual.setTime(model.getData());
	// }
	//
	// if (calAtual.get(Calendar.MONTH) != Calendar.getInstance().get(Calendar.MONTH)) {
	// calAtual.set(Calendar.DATE, calAtual.getActualMaximum(Calendar.DATE));
	// }
	//
	// final Calendar calInicial = Calendar.getInstance();
	// calInicial.set(Calendar.DATE, 1);
	// calInicial.set(Calendar.MONTH, calAtual.get(Calendar.MONTH));
	//
	// final SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
	// // SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy");
	//
	// String sql = " " + LancamentoDAO.COLUNA_DATA + " BETWEEN '" + df.format(calInicial.getTime()) + "' AND '" + df.format(calAtual.getTime())
	// + "' ";
	//
	// if (model.getCategoria() != null && model.getCategoria().getCodigo() != null) {
	// sql += " AND " + LancamentoDAO.COLUNA_CATEGORIA + " = " + model.getCategoria().getCodigo();
	// }
	//
	// return obterPorFiltro(sql);
	//
	// }

	@Override
	public PadraoDAOAb getDaoInstance() {
		return new LancamentoDAO(context);
	}

	public void importarLancamento() throws NegocioException {

		String lUrlArquivo = CustomSQLiteOpenHelper.DB_PATH_EXTERNO + "import.txt";

		try {

			InputStream is = new FileInputStream(lUrlArquivo);

			InputStreamReader isr = new InputStreamReader(is);
			BufferedReader br = new BufferedReader(isr);

			String s = br.readLine();

			while (s != null) {

				String lDataString = s.substring(0, 5) + "/" + Calendar.getInstance().get(Calendar.YEAR);
				String lObservacao = s.substring(5, s.indexOf("R$")).trim();
				String lValorString = s.substring(s.indexOf("R$") + 2).trim().replace(",", ".");

				final SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd", AndroidUtil.getLocalePadrao());
				final Date lDataLanc = new SimpleDateFormat("dd/MM/yyyy", AndroidUtil.getLocalePadrao()).parse(lDataString);
				String lDataSQLite = df.format(lDataLanc);

				final Double lValor = Double.parseDouble(lValorString);

				StringBuilder lSb = new StringBuilder();
				lSb.append(LancamentoDAO.COLUNA_DATA + "=='" + lDataSQLite + "'");
				lSb.append(" AND ");
				lSb.append(LancamentoDAO.COLUNA_VALOR + "==" + lValor);

				List<LancamentoModel> lList = obterPorFiltro(lSb.toString());

				if (lList.size() != 0) {
					LancamentoModel lModel = lList.iterator().next();
					lModel.setObservacao(lObservacao);

					editar(lModel);
				}

				else {
					LancamentoModel lModel = new LancamentoModel();
					lModel.setObservacao(lObservacao);
					lModel.setCategoria(new CategoriaModel(38)); // TODO Categoria "Visa Vale"
					lModel.setData(lDataLanc);
					lModel.setFormaPagamento(FormaPagamento.VISA_VALE);
					lModel.setValor(lValor);

					inserir(lModel);
				}

				s = br.readLine();
			}

			br.close();

		} catch (FileNotFoundException e) {
			throw new NegocioException(e, Mensagem.ERRO_GERAL);
		} catch (IOException e) {
			throw new NegocioException(e, Mensagem.ERRO_GERAL);
		} catch (ParseException e) {
			throw new NegocioException(e, Mensagem.ERRO_GERAL);
		}
	}

	@SuppressLint("SimpleDateFormat")
	public List<LancamentoModel> obterLancamentosPendentesAvaliacaoPorMes(Mes pMes) throws NegocioException {

		/*
		 * Configura o calendario para o mes atual
		 */
		final Calendar lCalInicio = Calendar.getInstance();
		lCalInicio.set(Calendar.MONTH, pMes.ordinal());
		// lCalInicio.set(Calendar.YEAR, Integer.valueOf(lAno));
		lCalInicio.set(Calendar.DAY_OF_MONTH, lCalInicio.getActualMinimum(Calendar.DAY_OF_MONTH));

		final Calendar lCalFim = Calendar.getInstance();
		lCalFim.set(Calendar.MONTH, pMes.ordinal());
		// lCalFim.set(Calendar.YEAR, Integer.valueOf(lAno));
		lCalFim.set(Calendar.DAY_OF_MONTH, lCalInicio.getActualMaximum(Calendar.DAY_OF_MONTH));

		SimpleDateFormat lSDF = new SimpleDateFormat("yyyy-MM-dd");

		String[] pColunsToReturn = new String[] {"C.NM_SIGLA", "C.NM_CATEGORIA", "C.ID_COR", "L.CD_LANCAMENTO", "L.DT_LANCAMENTO",
				"L.DS_OBSERVACAO, L.TP_FORMA_PAGAMENTO", "L.VL_LANCAMENTO"};

		String pGroupBy = "";
		String pWhere = " L.DT_LANCAMENTO BETWEEN '" + lSDF.format(lCalInicio.getTime()) + "' AND '" + lSDF.format(lCalFim.getTime())
				+ "' AND C.CD_SUPER_CATEGORIA = " + ConstantesSPGF.CODIGO_CATEGORIA_PENDENTE_AVALIACAO;

		// foo LEFT OUTER JOIN bar ON (foo.id = bar.foo_id)
		String pJoinTable = " TBLANCAMENTO L INNER JOIN TBCATEGORIA C ON L.CD_CATEGORIA = C.CD_CATEGORIA ";

		String pOrderBy = " L.DT_LANCAMENTO ";

		return new LancamentoDAO(context).obterPorFiltro(pJoinTable, pWhere, pColunsToReturn, pGroupBy, pOrderBy);
	}

	/**
	 * <PRE>
	 * 
	 * 		SELECT 
	 * 
	 * 		C.NM_SIGLA, C.NM_CATEGORIA, C.ID_COR, L.CD_LANCAMENTO, L.DT_LANCAMENTO, L.DS_OBSERVACAO, L.VL_LANCAMENTO 
	 * 
	 * 		FROM TBLANCAMENTO L
	 * 		INNER JOIN TBCATEGORIA C ON L.CD_CATEGORIA= C.CD_CATEGORIA
	 * 
	 * 		WHERE 1=1
	 * 		AND L.DT_LANCAMENTO BETWEEN '2014-01-01' AND '2014-01-31'
	 * 
	 * </PRE>
	 */

	@SuppressLint("SimpleDateFormat")
	public List<LancamentoModel> obterLancamentosPorMes(Mes mes) throws NegocioException {

		/*
		 * Configura o calendario para o mes atual
		 */
		final Calendar lCalInicio = Calendar.getInstance();
		lCalInicio.set(Calendar.MONTH, mes.ordinal());
		// lCalInicio.set(Calendar.YEAR, Integer.valueOf(lAno));
		lCalInicio.set(Calendar.DAY_OF_MONTH, lCalInicio.getActualMinimum(Calendar.DAY_OF_MONTH));

		final Calendar lCalFim = Calendar.getInstance();
		lCalFim.set(Calendar.MONTH, mes.ordinal());
		// lCalFim.set(Calendar.YEAR, Integer.valueOf(lAno));
		lCalFim.set(Calendar.DAY_OF_MONTH, lCalInicio.getActualMaximum(Calendar.DAY_OF_MONTH)); // Se for dia 31 e setar o mes 2 cai pro mes 3

		SimpleDateFormat lSDF = new SimpleDateFormat("yyyy-MM-dd");

		String sql = "SELECT C.NM_SIGLA, C.NM_CATEGORIA, C.ID_COR, L.CD_LANCAMENTO, L.DT_LANCAMENTO, L.DS_OBSERVACAO, L.VL_LANCAMENTO, L.TP_FORMA_PAGAMENTO FROM TBLANCAMENTO L INNER JOIN TBCATEGORIA C ON L.CD_CATEGORIA = C.CD_CATEGORIA	WHERE 1=1 AND L.DT_LANCAMENTO BETWEEN '"
				+ lSDF.format(lCalInicio.getTime()) + "' AND '" + lSDF.format(lCalFim.getTime()) + "' ORDER BY L.DT_LANCAMENTO";

		return new LancamentoDAO(context).executarQuery(sql, null);

	}

	// public List<LancamentoModel> obterLancamentosPosterioresMes(Mes pMes, String pAno) throws NegocioException {
	//
	// Calendar lCalendarInicio = Calendar.getInstance();
	// lCalendarInicio.set(Calendar.YEAR, Integer.valueOf(pAno));
	// lCalendarInicio.set(Calendar.MONTH, pMes.ordinal());
	// lCalendarInicio.set(Calendar.HOUR, 0);
	// lCalendarInicio.set(Calendar.MINUTE, 0);
	// lCalendarInicio.set(Calendar.SECOND, 0);
	// lCalendarInicio.set(Calendar.MILLISECOND, 0);
	//
	// Calendar lCalendarAtual = Calendar.getInstance();
	// lCalendarAtual.set(Calendar.HOUR, 0);
	// lCalendarAtual.set(Calendar.MINUTE, 0);
	// lCalendarAtual.set(Calendar.SECOND, 0);
	// lCalendarAtual.set(Calendar.MILLISECOND, 0);
	//
	// if (lCalendarInicio.getTime().equals(lCalendarAtual.getTime())) {
	// lCalendarInicio.set(Calendar.DAY_OF_MONTH, Calendar.getInstance().get(Calendar.DAY_OF_MONTH) + 1);
	// }
	//
	// else if (lCalendarInicio.after(lCalendarAtual)) {
	// lCalendarInicio.set(Calendar.DAY_OF_MONTH, lCalendarInicio.getMinimum(Calendar.DAY_OF_MONTH));
	// }
	//
	// else {
	// lCalendarInicio.set(Calendar.DAY_OF_MONTH, lCalendarInicio.getMaximum(Calendar.DAY_OF_MONTH));
	// }
	//
	// Calendar lCalendarFim = Calendar.getInstance();
	// lCalendarFim.set(Calendar.YEAR, Integer.valueOf(pAno));
	// lCalendarFim.set(Calendar.MONTH, pMes.ordinal());
	// lCalendarFim.set(Calendar.DAY_OF_MONTH, lCalendarFim.getMaximum(Calendar.DAY_OF_MONTH));
	//
	// final SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd", AndroidUtil.getLocalePadrao());
	// String sql = " " + LancamentoDAO.COLUNA_DATA + " BETWEEN '" + df.format(lCalendarInicio.getTime()) + "' AND '"
	// + df.format(lCalendarFim.getTime()) + "' ";
	//
	// return obterPorFiltro(sql);
	// }

}
